home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Magazine / Morphos / GCC / ppc-amigaos / include / va-ppc.h.old < prev    next >
Text File  |  1998-12-06  |  7KB  |  231 lines

  1. /* GNU C varargs support for the PowerPC with either the V.4 or Windows NT calling sequences */
  2.  
  3. #ifndef _WIN32
  4. /* System V.4 support */
  5. /* Define __gnuc_va_list.  */
  6.  
  7. #ifndef __GNUC_VA_LIST
  8. #define __GNUC_VA_LIST
  9.  
  10. #ifndef _SYS_VA_LIST_H
  11. #define _SYS_VA_LIST_H        /* Solaris sys/va_list.h */
  12.  
  13. /* Solaris decided to rename overflow_arg_area to input_arg_area,
  14.    so handle it via a macro.  */
  15. #define __va_overflow(AP) (AP)->overflow_arg_area
  16.  
  17. /* Note that the names in this structure are in the user's namespace, but
  18.    that the V.4 abi explicitly states that these names should be used.  */
  19. typedef struct __va_list_tag {
  20.   char gpr;            /* index into the array of 8 GPRs stored in the
  21.                    register save area gpr=0 corresponds to r3,
  22.                    gpr=1 to r4, etc. */
  23.   char fpr;            /* index into the array of 8 FPRs stored in the
  24.                    register save area fpr=0 corresponds to f1,
  25.                    fpr=1 to f2, etc. */
  26.   char *overflow_arg_area;    /* location on stack that holds the next
  27.                    overflow argument */
  28.   char *reg_save_area;        /* where r3:r10 and f1:f8, if saved are stored */
  29. } __va_list[1], __gnuc_va_list[1];
  30.  
  31. #else /* _SYS_VA_LIST */
  32.  
  33. typedef __va_list __gnuc_va_list;
  34. #define __va_overflow(AP) (AP)->input_arg_area
  35.  
  36. #endif /* not _SYS_VA_LIST */
  37. #endif /* not __GNUC_VA_LIST */
  38.  
  39. /* If this is for internal libc use, don't define anything but
  40.    __gnuc_va_list.  */
  41. #if defined (_STDARG_H) || defined (_VARARGS_H)
  42.  
  43. /* Register save area located below the frame pointer */
  44. #ifndef __VA_PPC_H__
  45. #define __VA_PPC_H__
  46. typedef struct {
  47.   long   __gp_save[8];        /* save area for GP registers */
  48.   double __fp_save[8];        /* save area for FP registers */
  49. } __va_regsave_t;
  50.  
  51. /* Macros to access the register save area */
  52. /* We cast to void * and then to TYPE * because this avoids
  53.    a warning about increasing the alignment requirement.  */
  54. #define __VA_FP_REGSAVE(AP,TYPE)                    \
  55.   ((TYPE *) (void *) (&(((__va_regsave_t *)                \
  56.              (AP)->reg_save_area)->__fp_save[(int)(AP)->fpr])))
  57.  
  58. #define __VA_GP_REGSAVE(AP,TYPE)                    \
  59.   ((TYPE *) (void *) (&(((__va_regsave_t *)                \
  60.              (AP)->reg_save_area)->__gp_save[(int)(AP)->gpr])))
  61.  
  62. /* Common code for va_start for both varargs and stdarg.  This depends
  63.    on the format of rs6000_args in rs6000.h.  The fields used are:
  64.  
  65.    #0    WORDS            # words used for GP regs/stack values
  66.    #1    FREGNO            next available FP register
  67.    #2    NARGS_PROTOTYPE        # args left in the current prototype
  68.    #3    ORIG_NARGS        original value of NARGS_PROTOTYPE
  69.    #4    VARARGS_OFFSET        offset from frame pointer of varargs area */
  70.  
  71. #define __va_words        __builtin_args_info (0)
  72. #define __va_fregno        __builtin_args_info (1)
  73. #define    __va_nargs        __builtin_args_info (2)
  74. #define __va_orig_nargs        __builtin_args_info (3)
  75. #define __va_varargs_offset    __builtin_args_info (4)
  76.  
  77. #define __va_start_common(AP, FAKE)                    \
  78. __extension__ ({                            \
  79.    register int __words = __va_words - FAKE;                \
  80.                                     \
  81.    (AP)->gpr = (__words < 8) ? __words : 8;                \
  82.    (AP)->fpr = __va_fregno - 33;                    \
  83.    (AP)->reg_save_area = (((char *) __builtin_frame_address (0))    \
  84.               + __va_varargs_offset);            \
  85.    __va_overflow(AP) = ((char *)__builtin_saveregs ()            \
  86.             + (((__words >= 8) ? __words - 8 : 0)        \
  87.                * sizeof (long)));                \
  88.    (void)0;                                \
  89. })
  90.  
  91. #ifdef _STDARG_H /* stdarg.h support */
  92.  
  93. /* Calling __builtin_next_arg gives the proper error message if LASTARG is
  94.    not indeed the last argument.  */
  95. #define va_start(AP,LASTARG) \
  96.   (__builtin_next_arg (LASTARG), __va_start_common (AP, 0))
  97.  
  98. #else /* varargs.h support */
  99.  
  100. #define va_start(AP) __va_start_common (AP, 1)
  101. #define va_alist __va_1st_arg
  102. #define va_dcl register int va_alist; ...
  103.  
  104. #endif /* _STDARG_H */
  105.  
  106. #ifdef _SOFT_FLOAT
  107. #define __va_float_p(TYPE)    0
  108. #else
  109. #define __va_float_p(TYPE)    (__builtin_classify_type(*(TYPE *)0) == 8)
  110. #endif
  111.  
  112. #define __va_longlong_p(TYPE) \
  113.   ((__builtin_classify_type(*(TYPE *)0) == 1) && (sizeof(TYPE) == 8))
  114.  
  115. #define __va_aggregate_p(TYPE)    (__builtin_classify_type(*(TYPE *)0) >= 12)
  116. #define __va_size(TYPE)        ((sizeof(TYPE) + sizeof (long) - 1) / sizeof (long))
  117.  
  118. #define va_arg(AP,TYPE)                            \
  119. __extension__ (*({                            \
  120.   register TYPE *__ptr;                            \
  121.                                     \
  122.   if (__va_float_p (TYPE) && (AP)->fpr < 8)                \
  123.     {                                    \
  124.       __ptr = __VA_FP_REGSAVE (AP, TYPE);                \
  125.       (AP)->fpr++;                            \
  126.     }                                    \
  127.                                     \
  128.   else if (__va_aggregate_p (TYPE) && (AP)->gpr < 8)            \
  129.     {                                    \
  130.       __ptr = * __VA_GP_REGSAVE (AP, TYPE *);                \
  131.       (AP)->gpr++;                            \
  132.     }                                    \
  133.                                     \
  134.   else if (!__va_float_p (TYPE) && !__va_aggregate_p (TYPE)        \
  135.        && (AP)->gpr + __va_size(TYPE) <= 8                \
  136.        && (!__va_longlong_p(TYPE)                    \
  137.            || (AP)->gpr + __va_size(TYPE) <= 8))            \
  138.     {                                    \
  139.       if (__va_longlong_p(TYPE) && ((AP)->gpr & 1) != 0)        \
  140.     (AP)->gpr++;                            \
  141.                                     \
  142.       __ptr = __VA_GP_REGSAVE (AP, TYPE);                \
  143.       (AP)->gpr += __va_size (TYPE);                    \
  144.     }                                    \
  145.                                     \
  146.   else if (!__va_float_p (TYPE) && !__va_aggregate_p (TYPE)        \
  147.        && (AP)->gpr < 8)                        \
  148.     {                                    \
  149.       (AP)->gpr = 8;                            \
  150.       __ptr = (TYPE *) (void *) (__va_overflow(AP));            \
  151.       __va_overflow(AP) += __va_size (TYPE) * sizeof (long);        \
  152.     }                                    \
  153.                                     \
  154.   else if (__va_aggregate_p (TYPE))                    \
  155.     {                                    \
  156.       __ptr = * (TYPE **) (void *) (__va_overflow(AP));            \
  157.       __va_overflow(AP) += sizeof (TYPE *);                \
  158.     }                                    \
  159.   else                                    \
  160.     {                                    \
  161.       __ptr = (TYPE *) (void *) (__va_overflow(AP));            \
  162.       __va_overflow(AP) += __va_size (TYPE) * sizeof (long);        \
  163.     }                                    \
  164.                                     \
  165.   __ptr;                                \
  166. }))
  167.  
  168. #define va_end(AP)    ((void)0)
  169.  
  170. /* Copy __gnuc_va_list into another variable of this type.  */
  171. #define __va_copy(dest, src) *(dest) = *(src)
  172.  
  173. #endif /* __VA_PPC_H__ */
  174. #endif /* defined (_STDARG_H) || defined (_VARARGS_H) */
  175.  
  176.  
  177. #else
  178. /* Windows NT */
  179. /* Define __gnuc_va_list.  */
  180.  
  181. #ifndef __GNUC_VA_LIST
  182. #define __GNUC_VA_LIST
  183. typedef char *__gnuc_va_list;
  184. #endif /* not __GNUC_VA_LIST */
  185.  
  186. /* If this is for internal libc use, don't define anything but
  187.    __gnuc_va_list.  */
  188. #if defined (_STDARG_H) || defined (_VARARGS_H)
  189.  
  190. #define __va_start_common(AP, LASTARG, FAKE)                \
  191.   ((__builtin_saveregs ()), ((AP) = ((char *) &LASTARG) + __va_rounded_size (AP)), 0)
  192.  
  193. #ifdef _STDARG_H /* stdarg.h support */
  194.  
  195. /* Calling __builtin_next_arg gives the proper error message if LASTARG is
  196.    not indeed the last argument.  */
  197. #define va_start(AP,LASTARG)                        \
  198.   (__builtin_saveregs (),                        \
  199.    (AP) = __builtin_next_arg (LASTARG),                    \
  200.    0)
  201.  
  202. #else /* varargs.h support */
  203.  
  204. #define va_start(AP)                            \
  205.   (__builtin_saveregs (),                        \
  206.    (AP) = __builtin_next_arg (__va_1st_arg) - sizeof (int),        \
  207.    0)
  208.  
  209. #define va_alist __va_1st_arg
  210. #define va_dcl register int __va_1st_arg; ...
  211.  
  212. #endif /* _STDARG_H */
  213.  
  214. #define __va_rounded_size(TYPE) ((sizeof (TYPE) + 3) & ~3)
  215. #define __va_align(AP, TYPE)                        \
  216.      ((((unsigned long)(AP)) + ((sizeof (TYPE) >= 8) ? 7 : 3))        \
  217.       & ~((sizeof (TYPE) >= 8) ? 7 : 3))
  218.  
  219. #define va_arg(AP,TYPE)                            \
  220. ( *(TYPE *)((AP = (char *) (__va_align(AP, TYPE)            \
  221.                 + __va_rounded_size(TYPE)))            \
  222.         - __va_rounded_size(TYPE)))
  223.  
  224. #define va_end(AP)    ((void)0)
  225.  
  226. /* Copy __gnuc_va_list into another variable of this type.  */
  227. #define __va_copy(dest, src) (dest) = (src)
  228.  
  229. #endif /* defined (_STDARG_H) || defined (_VARARGS_H) */
  230. #endif /* Windows NT */
  231.